package org.xml.parser.performanceTest;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.jdom2.Attribute;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.Book;
import org.xml.parser.SAX.SAXParserHandler;
import org.xml.sax.SAXException;

public class PerformanceTest {
	@Test
	public void testPerformance() {
		System.out.println("4种XML解析方式的性能比较（针对books.xml解析）：");
		long startTime = System.currentTimeMillis();
		domParser();
		System.out.println("DOM方式解析耗时：\t"
				+ (System.currentTimeMillis() - startTime) + "ms");
		startTime = System.currentTimeMillis();
		saxParser();
		System.out.println("SAX方式解析耗时：\t"
				+ (System.currentTimeMillis() - startTime) + "ms");
		startTime = System.currentTimeMillis();
		jdomParser();
		System.out.println("JDOM方式解析耗时：\t"
				+ (System.currentTimeMillis() - startTime) + "ms");
		startTime = System.currentTimeMillis();
		dom4jParser();
		System.out.println("DOM4J方式解析耗时：\t"
				+ (System.currentTimeMillis() - startTime) + "ms");
	}

	public static void domParser() {
		Book book = null;
		ArrayList<Book> books = new ArrayList<Book>();
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try {
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document document = db.parse("books.xml");
			NodeList bookList = document.getElementsByTagName("book");
			for (int i = 0; i < bookList.getLength(); i++) {
				book = new Book();
				Node bookNode = (Node) bookList.item(i);
				NamedNodeMap attributes = bookNode.getAttributes();

				// 遍历book节点的属性
				for (int j = 0; j < attributes.getLength(); j++) {
					Node attribute = attributes.item(j);
					if ("id".equals(attribute.getNodeName())) {
						book.setId(attribute.getNodeValue());
					}
				}

				// 解析book节点的子节点
				NodeList childNodes = bookNode.getChildNodes();
				// 遍历childNodes获取每个节点的节点名和节点值
				for (int j = 0; j < childNodes.getLength(); j++) {
					// 区分textNode和elementNode
					if (childNodes.item(j).getNodeType() == Node.ELEMENT_NODE) {
						if ("name".equals(childNodes.item(j).getNodeName())) {
							book.setName(childNodes.item(j).getFirstChild()
									.getNodeValue());
						} else if ("author".equals(childNodes.item(j)
								.getNodeName())) {
							book.setAuthor(childNodes.item(j).getTextContent());
						} else if ("year".equals(childNodes.item(j)
								.getNodeName())) {
							book.setYear(childNodes.item(j).getTextContent());
						} else if ("price".equals(childNodes.item(j)
								.getNodeName())) {
							book.setPrice(childNodes.item(j).getTextContent());
						} else if ("language".equals(childNodes.item(j)
								.getNodeName())) {
							book.setLanguage(childNodes.item(j)
									.getTextContent());
						}
					}
				}
				books.add(book);// 结束一本书的遍历的时候将其加入ArrayList中
			}

		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void saxParser() {
		// 1.获取一个SAXParserFactory的实例
		SAXParserFactory factory = SAXParserFactory.newInstance();
		try {
			// 2.通过factory获取SAXParser实例
			SAXParser parser = factory.newSAXParser();
			// 3.创建一个SAXParserHandler对象
			SAXParserHandler handler = new SAXParserHandler();
			// 4.通过SAXParser对象的parse（String uri,DefaultHandler dh）方法解析xml文件
			parser.parse("books.xml", handler);

			/* 将XML文件中的数据保存在Book对象中并将对象添加到ArrayList中，遍历ArrayList */
			ArrayList<Book> books = handler.getBookList();

		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void jdomParser() {
		ArrayList<Book> booksList = new ArrayList<Book>();
		// 1.创建一个SAXBuilder对象
		SAXBuilder saxBuilder = new SAXBuilder();

		InputStream in;
		try {
			// 2.创建一个输入流，将xml文件加载到输入流
			in = new FileInputStream("books.xml");
			// 3.通过SAXBuilder的build方法将输入流加载到SAXBuilder中
			org.jdom2.Document document = saxBuilder.build(in);
			// 4.通过Document对象获取xml文件的根节点
			Element rootElement = document.getRootElement();
			// 5.根据根节点获取子节点的List集合
			List<Element> bookList = rootElement.getChildren();
			// 使用循环对bookList进行遍历
			for (Element book : bookList) {
				Book bookEntity = new Book();

				// 不知道属性的个数和属性名的时候
				List<Attribute> attrList = book.getAttributes();
				// 遍历book的属性集合
				for (Attribute attribute : attrList) {
					if ("id".equals(attribute.getName())) {
						bookEntity.setId(attribute.getValue());
					}
				}
				// 对book节点的子节点的节点名和节点值进行遍历
				List<Element> bookChilds = book.getChildren();
				for (Element child : bookChilds) {
					if ("name".equals(child.getName())) {
						bookEntity.setName(child.getValue());
					} else if ("author".equals(child.getName())) {
						bookEntity.setAuthor((child.getValue()));
					} else if ("year".equals(child.getName())) {
						bookEntity.setYear((child.getValue()));
					} else if ("price".equals(child.getName())) {
						bookEntity.setPrice(child.getValue());
					} else if ("language".equals(child.getValue())) {
						bookEntity.setLanguage(child.getValue());
					}
				}
				booksList.add(bookEntity);
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (JDOMException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void dom4jParser() {
		ArrayList<Book> bookList = new ArrayList<Book>();
		Book b = null;
		// 1.创建一个SAXReader对象reader
		SAXReader reader = new SAXReader();
		try {
			// 2.通过reader对象的read方法加载xml文件，获取Document对象
			org.dom4j.Document document = reader.read(new File("books.xml"));
			org.dom4j.Element bookStore = document.getRootElement();
			// 获取根节点的子节点的相关信息
			Iterator iterator = bookStore.elementIterator();
			// 遍历迭代器,获取bookstore中的节点（book）
			while (iterator.hasNext()) {
				b = new Book();
				org.dom4j.Element book = (org.dom4j.Element) iterator.next();
				// 获取book的属性名和属性值
				List<org.dom4j.Attribute> bookAttrs = book.attributes();
				for (org.dom4j.Attribute attribute : bookAttrs) {
					if ("id".equals(attribute.getName())) {
						b.setId(attribute.getValue());
					}
				}
				// 获取book的子节点
				Iterator it = book.elementIterator();
				while (it.hasNext()) {
					org.dom4j.Element bookChild = (org.dom4j.Element) it.next();
					if ("name".equals(bookChild.getName())) {
						b.setName(bookChild.getStringValue());
					} else if ("author".equals(bookChild.getName())) {
						b.setAuthor(bookChild.getStringValue());
					} else if ("year".equals(bookChild.getName())) {
						b.setYear(bookChild.getStringValue());
					} else if ("price".equals(bookChild.getName())) {
						b.setPrice(bookChild.getStringValue());
					} else if ("language".equals(bookChild.getName())) {
						b.setLanguage(bookChild.getStringValue());
					}
				}
				bookList.add(b); // 将book对象添加到bookList集合中
			}

		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}
}
